/*
 * main.cpp
 *
 *  Created on: 6 mars 2011
 *      Author: Julien
 */
/*#include "LigneTramway.h"
#include "Station.h"
#include "Intersection.h"
*/
#include <iostream>
#include "Voiture.h"
#include "Rame.h"
#include "Traction.h"
#include "LigneTramway.h"
#include "Section.h"
#include "Intersection.h"
#include "Station.h"
#include "Conducteur.h"
#include "FeuSignalisation.h"
#include "FeuSignalisationTramway.h"
#include "FeuSignalisationCirculation.h"
#include "couleur.h"
#include "Passager.h"
#include  <signal.h>
using namespace std;

void attendreTerminaison();
pthread_t* getConducteur(int num);

void * affichageGeneral(void * param) {
	LigneTramway* lt = reinterpret_cast<LigneTramway*>(param);

	while(1)
        {
        	lt->afficherLigne();
        	sleep(1);
        	clrscr();
        }
	return 0;
}


int main(){
        cout << "/========== Création de l'environnement ==========/" << endl;
        LigneTramway lt(3);

        //---------------------------------------------------------------------
		// SECTION 1
		//---------------------------------------------------------------------
        Section* sec1 = new Section(7);
        lt.ajouterSection(sec1, 0);

        Station* s1 = new Station(sec1);
        lt[0]->ajouterElementSection(s1, 2);

        FeuSignalisationTramway * fdst0 = new FeuSignalisationTramway(false); // Feu rouge car une Rame dans la Section 0
        fdst0->demarrerThread();
		sec1->setFeuSignalisation(fdst0);


        //---------------------------------------------------------------------
        // SECTION 2
        //---------------------------------------------------------------------
        Section* sec2 = new Section(4);
        lt.ajouterSection(sec2, 1);

        FeuSignalisationTramway * fdst1 = new FeuSignalisationTramway(true);
        fdst1->demarrerThread();
		sec2->setFeuSignalisation(fdst1);

        Station* s2 = new Station(sec2);
        lt[0]->ajouterElementSection(s2, 4);

        Intersection* i1 = new Intersection(sec2);
        lt[1]->ajouterElementSection(i1, 2);

//        FeuSignalisationCirculation * fdsc1 = new FeuSignalisationCirculation(false);
 //       i1->setFeuSignalisation(fdsc1);

        //---------------------------------------------------------------------
        // SECTION 3
        //---------------------------------------------------------------------
        Section * sec3 = new Section(5);
        lt.ajouterSection(sec3, 2);

        FeuSignalisationTramway * fdst2 = new FeuSignalisationTramway(); // Par défaut, le feu est vert
        fdst2->demarrerThread();
		sec3->setFeuSignalisation(fdst2);

		Station* s3 = new Station(sec3,true);
		lt[2]->ajouterElementSection(s3, 4);

        //---------------------------------------------------------------------

        lt.afficherLigne();

        Voiture * voiture = new Voiture;
        Traction * traction = new Traction;
        traction->accelerer();
//        traction->accelerer();
//        traction->accelerer();
//        traction->accelerer();
//        traction->accelerer();
        Rame * rame = new Rame(voiture, traction);
        traction->setRame(rame);

        lt.deployerRame(rame, 0, 0);

        cout << "/========== Environnement créé ==========/" << endl;

        cout << "/========== Début de la simulation ==========/" << endl;

        //======= TEST DE DEPLACEMENT =======//
        /*cout<<"ATTENTE"<<endl;
        sleep(5);
        cout<<"DEPART !!!"<<endl;
        traction->avancer();
        sleep(3);
        traction->accelerer();
        cout << "ACCELERATION !!" << endl;
        sleep(10);
        traction->ralentir();
        cout << "RALENTISSEMENT !!" << endl;
        traction->stopper();
        cout<< "ON S'ARRETE !!" << endl;
        sleep(4);
        cout<< "ON REPART !!" << endl;
        traction->avancer();
        sleep(20);*/

        Conducteur * con = new Conducteur(rame);
        con->demarrerThread();
        //sleep(1);
        //cout << "Test de démarrage par le relais" << endl;
        //pccr->demarrerRames();
        //sleep(30);
        //pccr->arreterRames();
        //cout << "Fin du test" << endl;

        pthread_t threadAffichage;
    	if (pthread_create(&threadAffichage, 0, affichageGeneral, &lt) != 0) {
    		cout << "/!\\ Echec dans fonction Conducteur::demarrerThread. /!\\"
    				<< endl;
    	}


        pthread_t* conducteurThread = getConducteur(0);
        cout << "!!! Tentative d'envoi de messages au conducteur" << endl;
        pthread_kill(*conducteurThread,SIGUSR1);

        // Passagers !
        Passager * pass1 = new Passager(s1);
        pass1->demarrerThread();
        Passager * pass2 = new Passager(s1);
        pass2->demarrerThread();
        Passager * pass3 = new Passager(s1);
        pass3->demarrerThread();

        Passager * pass4 = new Passager(s2);
		pass4->demarrerThread();
		Passager * pass5 = new Passager(s2);
		pass5->demarrerThread();
		Passager * pass6 = new Passager(s2);
		pass6->demarrerThread();
		Passager * pass7 = new Passager(s2);
		pass7->demarrerThread();
		Passager * pass8 = new Passager(s2);
		pass8->demarrerThread();

        sleep(30);
    /*    pthread_kill(conducteurThread,SIGUSR2);
        sleep(5);
        pthread_kill(conducteurThread,SIGUSR1);
        sleep(6);
        pthread_kill(conducteurThread,SIGUSR2);
        cout << "!!! Fin tentative" << endl;
*/
		//======= TEST DE GESTION DES PORTES =======//
        /*cout << "Etat des portes ==> " <<flush;
		if(rame->getVoiture()->getEtatPortes()){
			cout << "Les portes sont fermées !" << endl;
		}
		rame->ouvrirPortes();

		cout << "Etat des portes ==> " <<flush;
		if(!rame->getVoiture()->getEtatPortes()){
			cout << "Les portes sont ouvertes !" << endl;
		}
		rame->fermerPortes();

		cout << "Etat des portes ==> " <<flush;
		if(rame->getVoiture()->getEtatPortes()){
			cout << "Les portes sont fermées !" << endl;
		}*/

		// On attend la terminaison de tous les threads avant la fin du programme.

        attendreTerminaison();
        cout << "/========== Fin de simulation atteinte ==========/" << endl; // Note : Pour l'instant jamais atteint car les threads ne s'arrêtent pas. TODO Faire s'arrêter les threads.



        return 0;
}

